package com.base.common.persistence;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Date;

import javax.persistence.Id;
import javax.xml.bind.annotation.XmlTransient;

import com.base.common.utils.IdGen;
import com.base.common.utils.Reflections;
import com.base.common.utils.StringUtils;

public abstract class Model<T> extends Entity<T> {

	private static final long serialVersionUID = 1L;

	protected String delFlag;
	protected Date createDate;
	protected Date modifyDate;
	
	public Model() {
		super();
		this.delFlag = DEL_FLAG_NORMAL;
	}

	public String getDelFlag() {
		return delFlag;
	}

	public void setDelFlag(String delFlag) {
		this.delFlag = delFlag;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	public Date getModifyDate() {
		return modifyDate;
	}

	public void setModifyDate(Date modifyDate) {
		this.modifyDate = modifyDate;
	}
	
	/**
	 * 是否是新记录（默认：false），调用setIsNewRecord()设置新记录，使用自定义ID。
	 * 设置为true后强制执行插入语句，ID不会自动生成，需从手动传入。
     * @return
     */
	@XmlTransient
	public boolean getIsNewRecord() {
        return isNewRecord || StringUtils.isBlank(getPrimaryKeyValue());
    }

	/**
	 * 是否是新记录（默认：false），调用setIsNewRecord()设置新记录，使用自定义ID。
	 * 设置为true后强制执行插入语句，ID不会自动生成，需从手动传入。
	 */
	public void setIsNewRecord(boolean isNewRecord) {
		this.isNewRecord = isNewRecord;
	}

	/**
	 * 插入之前执行方法，需要手动调用
	 */
	public void preInsert() {
		// 不限制ID为UUID，调用setIsNewRecord()使用自定义ID
		if (!this.isNewRecord) {
			setPrimaryKeyValue(IdGen.uuid());
		}

		this.modifyDate = new Date();
		this.createDate = this.modifyDate;
	}

	/**
	 * 更新之前执行方法，需要手动调用
	 */
	public void preUpdate() {
		this.modifyDate = new Date();
	}

	public boolean equals(Object obj) {
		if (null == obj) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		if (!getClass().equals(obj.getClass())) {
			return false;
		}
		Model<?> that = (Model<?>) obj;
		return null == this.getPrimaryKeyValue() ? false : this.getPrimaryKeyValue().equals(that.getPrimaryKeyValue());
	}
	
	public abstract String getPrimaryKeyValue();
	
	public abstract void setPrimaryKeyValue(String primaryKeyValue);
	
	
}
